/*
  对axios进行二次封装，完成以下功能：
    1. 复用请求地址 /api
    2. 请求成功，得到成功数据
    3. 请求失败，自动提示失败原因
      请求失败
      功能失败
    4. 携带公共请求参数
    5. 进度条
      nprogress
*/

import axios from "axios";
import NProgress from "nprogress";
import "nprogress/nprogress.css";

NProgress.configure({ showSpinner: false });

const errMessages = {
  401: "未授权",
  403: "禁止访问",
  404: "资源找不到",
  407: "token过期了",
  500: "服务器错误",
};

// 创建axios实例
// request简单理解：就是axios实例（和axios功能基本一致，但不完全一样）
const request = axios.create({
  baseURL: "/mock", // 请求公共路径（将来使用request发送请求，请求地址会自动添加baseURL）
  timeout: 20000, // 请求超时时间，超过时间会自动中断请求
  // headers: {},
});

/*
  发送请求流程：
    request() / request.get()
    请求拦截器
    发送请求
    响应拦截器
    await后面代码
*/
// 设置拦截器函数
// 请求拦截器
request.interceptors.request.use(
  (config) => {
    // 开始进度条
    NProgress.start();
    // config 就是请求的配置对象
    // 将来添加公共请求参数
    // config.headers.token = 'xxx';
    // 必须返回config
    return config;
  }
  // () => {}
);

// 响应拦截器
request.interceptors.response.use(
  // 成功回调 200 - 299
  (response) => {
    // 结束进度条
    NProgress.done();

    if (response.data.code === 200) {
      // 功能成功, 返回成功的数据
      return response.data.data;
    } else {
      // 功能失败，进行失败的错误提示
      alert(response.data.message || "未知错误，请联系管理员解决");
      return Promise.reject();
    }
  },
  // 失败回调 非 2xx 就是失败
  (error) => {
    /*
      error.message 失败原因
        请求超时 timeout of 1ms exceeded
        断网 Network Error
      error.response.status 响应状态码
    */
    // 结束进度条
    NProgress.done();

    if (error.response) {
      // 服务器有响应结果，但是失败
      // if (error.response.status === 401) {
      // } else if (error.response.status === 403) {
      // } else if (error.response.status === 404) {
      // }
      alert(errMessages[error.response.status] || "未知错误，请联系管理员解决");
    } else {
      // 服务器没有响应结果
      if (error.message.indexOf("timeout") !== -1) {
        alert("请求超时，网络不稳定或太慢了，请连接wifi试试");
      } else if (error.message.indexOf("Network") !== -1) {
        alert("断网了，请打开网络连接试试");
      } else {
        alert("未知错误，请联系管理员解决");
      }
    }

    return Promise.reject();
  }
);

// 暴露出去
export default request;
